/*
 * Copyright 2025 The JA-SIG Collaborative. All rights reserved.
 * distributed with this file and available online at
 */
package com.lap.auth.application.role;

import com.lap.auth.application.role.assembler.RoleAssembler;
import com.lap.auth.application.role.command.CreateRoleCmd;
import com.lap.auth.application.role.command.UpdateRoleCmd;
import com.lap.auth.application.role.dto.QueryRolePageQuery;
import com.lap.auth.application.role.dto.RoleDto;
import com.lap.auth.application.role.repository.RoleQueryRepository;
import com.lap.auth.domain.role.repository.RoleDataScopeRepository;
import com.lap.auth.domain.role.repository.RoleMenuRepository;
import com.lap.auth.domain.role.repository.RoleRepository;
import com.lap.auth.domain.role.service.RoleValidator;
import com.lap.framework.common.dto.page.PageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 角色应用服务层
 *
 * <ol>
 *   <li>不做业务规则，只做技术规则（加密/解密是技术实现，业务不关注）
 *   <li>取数，赋值，对象转换在这层执行
 *   <li>命名有规范，动词+领域名字
 *   <li>如查询比较多，建议分开领域QueryAppService,如:分页查询，分页查询返回关联字段
 * </ol>
 */
@RequiredArgsConstructor
@Service
public class RoleAppService {

  private final RoleAssembler roleAssembler;
  private final RoleValidator roleValidator;
  private final RoleRepository roleRepository;
  private final RoleMenuRepository roleMenuRepository;
  private final RoleDataScopeRepository roleDataScopeRepository;
  private final RoleQueryRepository roleQueryRepository;

  public PageResponse<RoleDto> queryRolesByPage(QueryRolePageQuery query) {
    return roleQueryRepository.findByConditionPaged(query);
  }

  public Integer createRole(CreateRoleCmd cmd) {
    roleValidator.validateCodeUnique(cmd.getCode());
    var role = roleAssembler.toDomain(cmd);
    return roleRepository.save(role);
  }

  public Integer updateRole(Integer id, UpdateRoleCmd cmd) {
    var role = roleValidator.assertRoleExists(id);
    role.changeInfo(cmd.getName(), cmd.getRemark());
    return roleRepository.save(role);
  }

  @Transactional(rollbackFor = Exception.class)
  public Integer deleteRole(Integer id) {
    roleValidator.assertRoleExists(id);
    roleMenuRepository.deleteByRoleId(id);
    roleDataScopeRepository.deleteByRoleId(id);
    return roleRepository.deleteById(id);
  }
}
